package com.wanqing.community.dao.util;

import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.support.SqlSessionDaoSupport;

import com.wanqing.community.util.ConditionParse;
/**
 * 封装MyBatis的基础DAO
 * All right reserved.
 * @version 
 * @param <T>
 * @param <PK>
 */
public class MyBatisDao<T,PK extends Serializable> extends SqlSessionDaoSupport{
	
	@Resource(name="sqlSessionFactory")
	private SqlSessionFactory sqlSessionFactory;
	
	@PostConstruct
	public void initSqlSessionFactory(){
		super.setSqlSessionFactory(sqlSessionFactory);
	}
	
	/**
	 * <p>Description:增加数据到数据库中<p>
	 * <p>modifiContent:</p>
	 * @param statementName 对应MyBatis SQL映射XML文件中的insert标签的ID
	 * @param entity 要保存的实体类
	 */
	protected int save(String statementName, T entity){
		return getSqlSession().insert(statementName, entity);
	}
	
	/**
	 * <p>Description:增加数据到数据库中<p>
	 * <p>modifiContent:</p>
	 * @param statementName 对应MyBatis SQL映射XML文件中的insert标签的ID
	 * @param map 要保存的数据，封装在Map里面，Map的Key为数据库中的字段
	 */
	protected int save(String statementName, Map<String, Object> map) {
		return getSqlSession().insert(statementName, map);
	}
	
	/**
	 * <p>Description:增加数据到数据库中<p>
	 * <p>modifiContent:</p>
	 * @param statementName 对应MyBatis SQL映射XML文件中的insert标签的ID
	 * @param obj 要保存的对象
	 */
	protected int saveObject(String statementName,Object obj){
		return getSqlSession().insert(statementName, obj);
	}
	
	/**
	 * <p>Description:批量增加记录<p>
	 * <p>modifiContent:</p>
	 * @param statementName 对应MyBatis SQL映射XML文件中的insert标签的ID
	 * @param collections 要增加的记录对象的集合
	 */
	protected int saveBatchObject(String statementName,Collection<?> collections){
		return getSqlSession().insert(statementName, collections);
	}
	
	/**
	 * <p>Description:批量增加记录<p>
	 * <p>modifiContent:</p>
	 * @param statementName 对应MyBatis SQL映射XML文件中的insert标签的ID
	 * @param lists 要增加的记录对象的集合
	 */
	protected int saveBatch(String statementName,List<T> lists){
		return getSqlSession().insert(statementName, lists);			
	}
	
	/**
	 * <p>Description:批量增加记录<p>
	 * <p>modifiContent:</p>
	 * @param statementName 对应MyBatis SQL映射XML文件中的insert标签的ID
	 * @param lists 要增加的记录对象的集合
	 */
	protected int saveBatchForMap(String statementName,List<Map<String, Object>> lists){
		return getSqlSession().insert(statementName, lists);			
	}
	
	/**
	 * <p>Description:根据主键ID的查找一条记录,用于单表查找<p>
	 * <p>modifiContent:</p>
	 * @param statementName 要执行的SQL对应MyBatis中的ID
	 * @param paramPK 要查找的记录ID
	 * @return 
	 */
	protected T findObjectById(String statementName,PK paramPK){
		return getSqlSession().selectOne(statementName, paramPK);		
	}
	
	/**
	 * <p>Description:根据主键ID的查找一条记录的第一行第一列<p>
	 * <p>modifiContent:</p>
	 * @param statementName 要执行的SQL对应MyBatis中的ID
	 * @param paramPK 要查找的记录ID
	 * @return 
	 */
	protected String GetScalar(String statementName,PK paramPK){
		return getSqlSession().selectOne(statementName, paramPK);		
	}
	
	/**
	 * <p>Description:根据条件得到记录数<p>
	 * <p>modifiContent:</p>
	 * @param statementName 要执行的SQL对应MyBatis中的ID
	 * @param condParse 封装查询条件
	 * @return int
	 */
	protected int getCount(String statementName,ConditionParse condParse){
		return getSqlSession().selectOne(statementName, condParse.getCondition());
	}
	
	/**
	 * <p>Description:根据条件得到记录数<p>
	 * <p>modifiContent:<p>
	 * @param statementName 要执行的SQL对应MyBatis中的ID
	 * @param map 封装查询条件
	 * @return
	 */
	protected int getCount(String statementName,Map<String, Object> map){
		return getSqlSession().selectOne(statementName, map);
	}
	
	/**
	 * <p>Description:修改记录<p>
	 * <p>modifiContent:</p>
	 * @param statementName 要执行的SQL对应MyBatis中的ID
	 * @param entity 要修改的实体类
	 */
	protected int update(String statementName,T entity){
		return getSqlSession().update(statementName, entity);
	}
	
	/**
	 * <p>Description:批量修改记录<p>
	 * <p>modifiContent:<p>
	 * @param statementName
	 * @param lists
	 * @return
	 */
	protected int updateBatch(String statementName,List<T> lists){
		return getSqlSession().update(statementName, lists);
	}
	
	/**
	 * <p>Description:根据条件修改记录<p>
	 * <p>modifiContent:</p>
	 * @param statementName 要执行的SQL对应MyBatis中的ID
	 * @param condParse 封装条件
	 */
	protected int update(String statementName,ConditionParse condParse){
		return getSqlSession().update(statementName, condParse.getCondition());
	}
	
	/**
	 * <p>Description:根据条件修改记录<p>
	 * <p>modifiContent:</p>
	 * @param statementName 要执行的SQL对应MyBatis中的ID
	 * @param map 要修改的数据，封装在Map里面，Map的Key为数据库中的字段
	 */
	protected int update(String statementName,Map<String, Object> map){
		return getSqlSession().update(statementName, map);
	}
	
	/**
	 * <p>Description:批量修改记录<p>
	 * <p>modifiContent:<p>
	 * @param statementName
	 * @param lists
	 * @return
	 */
	protected int updateBatchForMap(String statementName,List<Map<String, Object>> lists){
		return getSqlSession().update(statementName, lists);
	}
	/**
	 * <p>Description:修改记录<p>
	 * <p>modifiContent:</p>
	 * @param statementName 对应MyBatis SQL映射XML文件中的insert标签的ID
	 * @param obj 要修改的对象
	 */
	protected int updateObject(String statementName,Object obj){
		return getSqlSession().update(statementName, obj);
	}
	
	/**
	 * <p>Description:批量修改记录<p>
	 * <p>modifiContent:</p>
	 * @param statementName 对应MyBatis SQL映射XML文件中的insert标签的ID
	 * @param obj 要修改的对象
	 */
	protected int updateBatchObject(String statementName,Collection<?> collections){
		return getSqlSession().update(statementName, collections);
	}
	
	
	/**
	 * <p>Description:根据主键ID的删除一条记录<p>
	 * <p>modifiContent:</p>
	 * @param statementName 要执行的SQL对应MyBatis中的ID
	 * @param paramPK 要删除的记录ID
	 */
	protected int delete(String statementName,PK paramPK){
		return getSqlSession().delete(statementName, paramPK);
	}
	
	/**
	 * <p>Description:根据Map中封装的条件删除数据<p>
	 * <p>modifiContent:<p>
	 * @param statementName 要执行的SQL对应MyBatis中的ID
	 * @param map
	 * @return
	 */
	protected int delete(String statementName,Map<String, Object> map){
		return getSqlSession().delete(statementName, map);
	}
	
	/**
	 * <p>Description:根据主键ID的批量删除记录<p>
	 * <p>modifiContent:</p>
	 * @param statementName  要执行的SQL对应MyBatis中的ID
	 * @param list 要删除的记录ID的集合
	 */
	protected int deleteBatchById(String statementName,List<String> list){
		return getSqlSession().delete(statementName, list);
	}
	
	/**
	 * <p>Description:批量删除记录<p>
	 * <p>modifiContent:</p>
	 * @param statementName  要执行的SQL对应MyBatis中的ID
	 * @param list 要删除的记录ID的集合
	 */
	protected int deleteBatch(String statementName,List<T> list){
		return getSqlSession().delete(statementName, list);
	}
	
	/**
	 * <p>Description:根据自定义条件删除记录<p>
	 * <p>modifiContent:<p>
	 * @param statementName 要执行的SQL对应MyBatis中的ID
	 * @param condParse 封装条件
	 * @return
	 */
	protected int delete(String statementName,ConditionParse condParse){
		return getSqlSession().delete(statementName, condParse.getCondition());
	}
	
	/**
	 * <p>Description:根据某个条件删除记录<p>
	 * <p>modifiContent:<p>
	 * @param statementName 要执行的SQL对应MyBatis中的ID
	 * @param condParse 封装条件
	 * @return
	 */
	protected int deleteByCondition(String statementName,String condition){
		return getSqlSession().delete(statementName, condition);
	}
	
	/**
	 * <p>Description:查询集合<p>
	 * <p>modifiContent:</p>
	 * @param statementName 要执行的SQL对应MyBatis中的ID
	 * @return List<T>
	 */
	protected List<T> queryForList(String statementName){
		return getSqlSession().selectList(statementName);
	}
	
	/**
	 * <p>Description:根据条件查询集合<p>
	 * <p>modifiContent:</p>
	 * @param statementName 要执行的SQL对应MyBatis中的ID
	 * @param condParse 封装查询条件
	 * @return List<T>
	 */
	protected List<T> queryForList(String statementName,ConditionParse condParse){
		return getSqlSession().selectList(statementName, condParse.getCondition());
	}
	
	/**
	 * <p>Description:根据条件查询集合<p>
	 * <p>modifiContent:</p>
	 * @param statementName 要执行的SQL对应MyBatis中的ID
	 * @param condParse 封装查询条件
	 * @return List<T>
	 */
	protected List<T> queryForList(String statementName,Map<String, Object> map){
		return getSqlSession().selectList(statementName, map);
	}
	
	protected List<T> queryForList(String statementName,String parParam){
		return getSqlSession().selectList(statementName,parParam);
	}
	
	
	
	/**
	 * 
	 * <p>Description:根据条件分页查询集合<p>
	 * <p>modifiContent:</p>
	 * @param statementName 要执行的SQL对应MyBatis中的ID
	 * @param condParse 封装查询条件
	 * @param currPage 当前页
	 * @param pageSize 每页显示的记录条数
	 * @return List<T>
	 */
	protected List<T> queryForList(String statementName,ConditionParse condParse,int currPage, int pageSize){
		pageSize=(pageSize>0)?pageSize:10;
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("pageNo", (currPage-1)*pageSize);
		//map.put("pageSize", pageSize * currPage);
		map.put("pageSize", pageSize);
		map.put("keyName", condParse.getCondition());		
		return getSqlSession().selectList(statementName, map);
	}
	
	/**
	 * 
	 * <p>Description:根据条件分页查询集合<p>
	 * <p>modifiContent:</p>
	 * @param statementName 要执行的SQL对应MyBatis中的ID
	 * @param condParse 封装查询条件
	 * @param currPage 当前页
	 * @param pageSize 每页显示的记录条数
	 * @return List<T>
	 */
	protected List<T> queryForList(String statementName,Map<String, Object> map,int currPage, int pageSize){		
		pageSize=(pageSize>0)?pageSize:10;
		map.put("pageNo", (currPage-1)*pageSize);
		//map.put("pageSize", pageSize * currPage);	
		map.put("pageSize", pageSize);
		return getSqlSession().selectList(statementName, map);
	}
	
	/**
	 * <p>Description:根据条件查询集合<p>
	 * <p>modifiContent:<p>
	 * @param <E>
	 * @param statementName 要执行的SQL对应MyBatis中的ID
	 * @param condParse 封装查询条件
	 * @return
	 */
	protected <E> List<E> queryForListE(String statementName,ConditionParse condParse){
		return getSqlSession().selectList(statementName, condParse.getCondition());
	}
	
	/**
	 * <p>Description:<p>
	 * <p>modifiContent:<p>
	 * @param <E>
	 * @param statementName 要执行的SQL对应MyBatis中的ID
	 * @return
	 */
	protected <E> List<E> queryForListE(String statementName){
		return getSqlSession().selectList(statementName);
	}	
	
	/**
	 * <p>Description:根据组合条件查找单记录对象<p>
	 * <p>modifiContent:</p>
	 * @param statementName 要执行的SQL对应MyBatis中的ID
	 * @param condParse 封装查询条件
	 * @return T
	 */
	protected T queryForEntity(String statementName,ConditionParse condParse){
		return getSqlSession().selectOne(statementName, condParse.getCondition());
	}
	
	/**
	 * <p>Description:根据组合条件查找单记录对象<p>
	 * <p>modifiContent:</p>
	 * @param statementName 要执行的SQL对应MyBatis中的ID
	 * @param condParse 封装查询条件
	 * @return T
	 */
	protected T queryForEntity(String statementName,Map<String, Object> map){
		return getSqlSession().selectOne(statementName, map);
	}
	
	/**
	 * <p>Description:查询集合<p>
	 * <p>modifiContent:</p>
	 * @param statementName 要执行的SQL对应MyBatis中的ID
	 * @return List<Map<String, Object>>
	 */
	protected List<Map<String, Object>> queryForListMap(String statementName){
		return getSqlSession().selectList(statementName);
	}
	
	/**
	 * <p>Description:根据条件查询集合<p>
	 * <p>modifiContent:</p>
	 * @param statementName 要执行的SQL对应MyBatis中的ID
	 * @param condParse 封装查询条件
	 * @return List<Map<String, Object>>
	 */
	protected List<Map<String, Object>> queryForListMap(String statementName,ConditionParse condParse){
		return getSqlSession().selectList(statementName, condParse.getCondition());
	}
	
	/**
	 * <p>Description:根据条件查询集合<p>
	 * <p>modifiContent:<p>
	 * @param statementName 要执行的SQL对应MyBatis中的ID
	 * @param map
	 * @return
	 */
	protected List<Map<String, Object>> queryForListMap(String statementName,Map<String, Object> map){
		return getSqlSession().selectList(statementName, map);
	}
	
	/**
	 * 
	 * <p>Description:根据条件分页查询集合<p>
	 * <p>modifiContent:</p>
	 * @param statementName 要执行的SQL对应MyBatis中的ID
	 * @param condParse 封装查询条件
	 * @param currPage 当前页
	 * @param pageSize 每页显示的记录条数
	 * @return List<Map<String, Object>>
	 */
	protected List<Map<String, Object>> queryForListMap(String statementName,ConditionParse condParse,int currPage, int pageSize){
		pageSize=(pageSize>0)?pageSize:10;
		Map<String, Object> map = new HashMap<String, Object>();		
		//map.put("pageNo", currPage);
		//map.put("pageSize", pageSize + currPage);
		map.put("pageSize", currPage*pageSize);
		//map.put("pageNo", (currPage-1)*pageSize);
		map.put("pageSize", pageSize);
		map.put("keyName", condParse.getCondition());
		return getSqlSession().selectList(statementName, map);
	}
	
	/**
	 * 
	 * <p>Description:根据条件分页查询集合<p>
	 * <p>modifiContent:</p>
	 * @param statementName 要执行的SQL对应MyBatis中的ID
	 * @param condParse 封装查询条件
	 * @param currPage 当前页
	 * @param pageSize 每页显示的记录条数
	 * @return List<Map<String, Object>>
	 */
	protected List<Map<String, Object>> queryForListMap(String statementName,Map<String, Object> map,int currPage, int pageSize){	
		pageSize=(pageSize>0)?pageSize:10;
		map.put("pageSize", currPage*pageSize);
		map.put("pageNo", (currPage-1)*pageSize);		
		return getSqlSession().selectList(statementName, map);
	}
	
	/**
	 * <p>Description:根据组合条件查找单条记录，并将此条记录封装到Map中<p>
	 * <p>modifiContent:</p>
	 * @param statementName 要执行的SQL对应MyBatis中的ID
	 * @param condParse 封装查询条件
	 * @return Map<String, Object>
	 */
	protected Map<String, Object> queryForMap(String statementName,ConditionParse condParse){
		return getSqlSession().selectOne(statementName,condParse.getCondition());
	}
	
	/**
	 * <p>Description:根据条件查询集合<p>
	 * <p>modifiContent:<p>
	 * @param statementName 要执行的SQL对应MyBatis中的ID
	 * @param map
	 * @return
	 */
	protected Map<String, Object> queryForMap(String statementName,Map<String, Object> map){
		return getSqlSession().selectOne(statementName, map);
	}
}
